package org.cybzacg.convert.listener.impl;

import lombok.Getter;
import org.cybzacg.convert.context.ConversionContext;
import org.cybzacg.convert.listener.ConversionListener;

/**
 * 性能监听器
 * 监控转换性能
 */
@Getter
public class PerformanceListener extends ConversionListener.Adapter{

    private volatile long totalConversions = 0;
    private volatile long successfulConversions = 0;
    private volatile long failedConversions = 0;
    private volatile long totalDuration = 0;
    private volatile long minDuration = Long.MAX_VALUE;
    private volatile long maxDuration = Long.MIN_VALUE;

    @Override
    public void onConversionStart(ConversionContext context, Object source) {
        context.setProperty("startTime", System.nanoTime());
    }

    @Override
    public void onConversionSuccess(ConversionContext context, Object source, Object result) {
        recordMetrics(context, true);
    }

    @Override
    public void onConversionFailure(ConversionContext context, Object source, Exception exception) {
        recordMetrics(context, false);
    }

    private void recordMetrics(ConversionContext context, boolean success) {
        Long startTime = context.getProperty("startTime");
        if (startTime != null) {
            long duration = System.nanoTime() - startTime;

            synchronized (this) {
                totalConversions++;
                totalDuration += duration;
                minDuration = Math.min(minDuration, duration);
                maxDuration = Math.max(maxDuration, duration);

                if (success) {
                    successfulConversions++;
                } else {
                    failedConversions++;
                }
            }
        }
    }

    /**
     * 获取性能统计
     *
     * @return 性能统计信息
     */
    public String getPerformanceStats() {
        synchronized (this) {
            double successRate = totalConversions > 0 ? (double) successfulConversions / totalConversions * 100 : 0;
            double avgDurationMs = totalConversions > 0 ? (double) totalDuration / totalConversions / 1_000_000 : 0;

            return String.format(
                    "PerformanceStats{total=%d, success=%d, failed=%d, successRate=%.2f%%, " +
                            "avgDuration=%.3fms, minDuration=%.3fms, maxDuration=%.3fms}",
                    totalConversions, successfulConversions, failedConversions, successRate,
                    avgDurationMs, minDuration / 1_000_000.0, maxDuration / 1_000_000.0);
        }
    }

    /**
     * 重置统计信息
     */
    public void resetStats() {
        synchronized (this) {
            totalConversions = 0;
            successfulConversions = 0;
            failedConversions = 0;
            totalDuration = 0;
            minDuration = Long.MAX_VALUE;
            maxDuration = Long.MIN_VALUE;
        }
    }
}
